﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.IO;

namespace Coding4FunCamera
{

    public interface ICameraFilter
    {
        Bitmap Apply();
    }
    public class ColorFilter:ICameraFilter
    {
        private string _fileName;
        public ColorFilter(string fileName)
        {
            if (!File.Exists(fileName))
            {
                throw new ApplicationException("Cannot apply Camera filter to a file that doesn't exist");
            }
            else
            {
                this._fileName = fileName;
            }
        }
        #region ICameraFilter Members

        public Bitmap Apply()
        {
            return new Bitmap(_fileName);
        }

        #endregion
    }
    public class BlackAndWhiteFilter : ICameraFilter
    {
        private string _fileName;
        public BlackAndWhiteFilter(string fileName)
        {
            if (!File.Exists(fileName))
            {
                throw new ApplicationException("Cannot apply Camera filter to a file that doesn't exist");
            }
            else
            {
                this._fileName = fileName;
            }
        }

        #region ICameraFilter Members

        public Bitmap Apply()
        {
            Bitmap newBitmap;

            using (Bitmap original = new Bitmap(_fileName))
            {
                //make an empty bitmap the same size as original
                newBitmap =
                   new Bitmap(original.Width, original.Height);

                for (int i = 0; i < original.Width; i++)
                {
                    for (int j = 0; j < original.Height; j++)
                    {
                        //get the pixel from the original image
                        Color originalColor = original.GetPixel(i, j);

                        //create the grayscale version of the pixel
                        int grayScale =
                           (int)((originalColor.R * .3) +
                                  (originalColor.G * .59) +
                                  (originalColor.B * .11));

                        //create the color object
                        Color newColor =
                           Color.FromArgb(grayScale, grayScale, grayScale);

                        //set the new image's pixel to the grayscale version
                        newBitmap.SetPixel(i, j, newColor);
                    }
                }
            }
            return newBitmap;
        }
        
        #endregion
    }

    public class SepiaFilter : ICameraFilter
    {
        private string _fileName;
        public SepiaFilter(string fileName)
        {
            if (!File.Exists(fileName))
            {
                throw new ApplicationException("Cannot apply Camera filter to a file that doesn't exist");
            }
            else
            {
                this._fileName = fileName;
            }
        }
        #region ICameraFilter Members

        public Bitmap Apply()
        {
            Bitmap newBitmap;

            using (Bitmap original = new Bitmap(_fileName))
            {
                //make an empty bitmap the same size as original
                newBitmap =
                   new Bitmap(original.Width, original.Height);

                for (int i = 0; i < original.Width; i++)
                {
                    for (int j = 0; j < original.Height; j++)
                    {
                        //get the pixel from the original image
                        Color originalColor = original.GetPixel(i, j);

                        double outputRed = (originalColor.R * .393) + (originalColor.G *.769) + (originalColor.B * .189);
                        double outputGreen = (originalColor.R * .349) + (originalColor.G *.686) + (originalColor.B * .168);
                        double outputBlue = (originalColor.R * .272) + (originalColor.G * .534) + (originalColor.B * .131);

                        int ioutputRed = Convert.ToInt16(outputRed);
                        int ioutputGreen = Convert.ToInt16(outputGreen);
                        int ioutputBlue = Convert.ToInt16(outputBlue);                        

                        if (ioutputRed > 255)
                        {
                            ioutputRed = 255;
                        }

                        if (ioutputGreen > 255)
                        {
                            ioutputGreen = 255;
                        }

                        if (ioutputBlue > 255)
                        {
                            ioutputBlue = 255;
                        }


                        //create the color object
                        Color newColor =
                           Color.FromArgb(ioutputRed, ioutputGreen, ioutputBlue);

                        //set the new image's pixel to the Sepia version
                        newBitmap.SetPixel(i, j, newColor);
                    }
                }
            }
            return newBitmap;
        }

        #endregion
    }
}
